package dao;

import java.awt.List;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class BaseSql<T> {
	private Class<T> entity;
	private String tablename;
	private Connection conn;

	@SuppressWarnings("unchecked")
	public BaseSql() {
		ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
		entity = (Class<T>) type.getActualTypeArguments()[0];
		tablename = entity.getSimpleName();
		conn = DBUtil.getConnection();
	}

	public void insert(T o) {
		StringBuffer sql = new StringBuffer("insert into " + tablename + "(");
		Field[] fd = entity.getDeclaredFields();
		for (int i = 0; i < fd.length; i++) {
			sql.append(fd[i].getName());
			if (i < fd.length - 1)
				sql.append(",");
			else
				sql.append(") values(");
		}
		for (int i = 0; i < fd.length; i++) {
			sql.append("?");
			if (i < fd.length - 1)
				sql.append(",");
			else
				sql.append(")");
		}
		System.out.println(sql.toString());
		try {
			PreparedStatement pstm = conn.prepareStatement(sql.toString());
			for (int i = 0; i < fd.length; i++) {
				fd[i].setAccessible(true);
				Object val = fd[i].get(o);
				pstm.setObject(i + 1, val);
			}
			pstm.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void delete(Integer id) {
		Field[] fields = entity.getDeclaredFields();
		String sql = "delete from " + tablename + " where " + fields[0].getName() + "=" + id;
		System.out.println(sql);
		try {
			Statement stm = conn.createStatement();
			stm.executeQuery(sql);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public void update(T o) {
		Field[] fields = entity.getDeclaredFields();
		StringBuffer sql = new StringBuffer("update " + tablename + " set ");
		for (int i = 1; i < fields.length; i++) {
			sql.append(fields[i].getName() + "=?");
			if (i < fields.length - 1)
				sql.append(",");
			else
				sql.append(" where " + fields[0].getName() + "=?");
		}
		System.out.println(sql.toString());
		try {
			PreparedStatement pstm = conn.prepareStatement(sql.toString());
			for (int i = 1; i < fields.length; i++) {
				fields[i].setAccessible(true);
				Object val = fields[i].get(o);

				pstm.setObject(i, val);
			}
			fields[0].setAccessible(true);
			Object val = fields[0].get(o);
			pstm.setObject(fields.length, val);
			pstm.executeUpdate();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public T getOne(T o) {
		StringBuffer sql = new StringBuffer("select * from " + tablename + " where ");
		Field[] fields = entity.getDeclaredFields();
		sql.append(fields[0].getName() + "=?");
		try {
			PreparedStatement pstm = conn.prepareStatement(sql.toString());
			fields[0].setAccessible(true);
			Object val = fields[0].get(o);
			pstm.setObject(1, val);
			System.out.println(sql);
			ResultSet rs = pstm.executeQuery();
			rs.next();
			
			T one=entity.newInstance();
			for (int i = 0; i < fields.length; i++) {
				fields[i].setAccessible(true);
				Object fv=rs.getObject(i+1);
				if(fields[i].getType().getSimpleName().equals("Integer")){
					BigDecimal bd=(BigDecimal) fv;
					fv=bd.intValue();
				}
				fields[i].set(one, fv);
			}
			return one;

		} catch (SQLException e) {

			e.printStackTrace();
			
		} catch (IllegalArgumentException e) {

			e.printStackTrace();		
		} catch (IllegalAccessException e) {

			e.printStackTrace();
		} catch (InstantiationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}

	public List getAll() {
		return null;
	}
}
